package org.maxkey.portal.core.ticket;


import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
 * This is {@link AbstractRandomStringGenerator}.
 * <p>
 * Implementation of the RandomStringGenerator that allows you to define the
 * length of the random part.
 *
 * @author Timur Duehr
 * @since 5.2.0
 */
public abstract class AbstractRandomStringGenerator implements RandomStringGenerator {
	private static final String NATIVE_NON_BLOCKING_ALGORITHM = "SHA1PRNG";
    /**
     * An instance of secure random to ensure randomness is secure.
     */
    protected final SecureRandom randomizer =getInstance(NATIVE_NON_BLOCKING_ALGORITHM);

    /**
     * Default string length before encoding.
     */
    protected final int defaultLength;
    
    public static SecureRandom getInstance(String algorithm)
              {
    	try{
    		  return SecureRandom.getInstance(NATIVE_NON_BLOCKING_ALGORITHM);
    	}catch(NoSuchAlgorithmException e){
    		e.printStackTrace();
    		return new SecureRandom();
    	}
    }
    

    /**
     * Instantiates a new default random string generator
     * with length set to {@link RandomStringGenerator#DEFAULT_LENGTH}.
     */
    public AbstractRandomStringGenerator() {
        this.defaultLength = DEFAULT_LENGTH;
    }

    /**
     * Instantiates a new default random string generator.
     *
     * @param defaultLength the max random length
     */
    public AbstractRandomStringGenerator(final int defaultLength) {
        this.defaultLength = defaultLength;
    }

    @Override
    public String getAlgorithm() {
        return randomizer.getAlgorithm();
    }

    /**
     * Converts byte[] to String by simple cast. Subclasses should override.
     *
     * @param random raw bytes
     * @return a converted String
     */
    protected String convertBytesToString(final byte[] random) {
        return new String(random, StandardCharsets.UTF_8);
    }

    @Override
    public String getNewString(final int size) {
    	byte[] random = getNewStringAsBytes(size);
        return convertBytesToString(random);
    }

    @Override
    public String getNewString() {
        return getNewString(getDefaultLength());
    }

    @Override
    public byte[] getNewStringAsBytes(final int size) {
    	byte[] random = new byte[size];
        this.randomizer.nextBytes(random);
        return random;
    }

    @Override
    public byte[] getNewStringAsBytes() {
        return this.getNewStringAsBytes(this.getDefaultLength());
    }
}
